package com.xb.loan.cashier.biz.pay;

import com.alibaba.druid.util.StringUtils;
import com.xb.loan.util.log.DefaultLoggerFacotry;
import org.slf4j.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * 支付充值工厂类
 * 支付充值工厂类
 */
public class PaymentChargeManager {

	private static final Logger logger = DefaultLoggerFacotry.getLogger(PaymentChargeManager.class);

	// 所有支付对象的集合
	private static Map<String, IPaymentForCharge> paymentManagerMap = new HashMap<String, IPaymentForCharge>();;
	// 支付方式对应支付对象property路径
	private static final String PROPERTIES_PATH = "config/payment_config.properties";
	// 支付类型标志
	private static final String CHANNEL_TYPE = "payChannel_";
	// 支付类型与支付类型名称对应集合
	private static Map<Integer, String> channelMap = new HashMap<Integer, String>();

	static {
		// 初始化
		init();
	}

	/**
	 * 通过支付方式字符串获得对应的支付对象类
	 * 
	 * @param paymentGateway 支付方式字符串
	 * @return 支付对象类
	 * 2016年6月3日 by lh.qiu
	 */
	public static IPaymentForCharge getPaymentGateway(String paymentGateway) {

		return paymentManagerMap.get(paymentGateway);
	}
	
	/**
	 * 通过支付类型码获得对应的支付对象类
	 * 
	 * @param paymentChannelType 支付类型码
	 * @return 支付对象类
	 * 2016年6月7日 by lh.qiu
	 */
	public static IPaymentForCharge getPaymentGateway(Integer paymentChannelType) {
		String keys = channelMap.get(paymentChannelType);
		if(!StringUtils.isEmpty(keys)) {
			return paymentManagerMap.get(keys);
		}
		return null;
	}

	/**
	 * 工厂初始化方法 从配置文件中读取支付方式，创建支付方式对象类，将支付方式与支付方式对象类放入集合中
	 * 
	 * 2016年6月3日 by lh.qiu
	 */
	private static void init() {

		Properties props = readAsProperties(PROPERTIES_PATH);

		Set<Object> keys = props.keySet();
		String keyStr = "";
		int channelKey = 0;

		for (Object key : keys) {
			keyStr = key.toString();
			// 如果是支付类型（以支付类型标志开始），将支付类型与支付类型名称放入Map中
			if(keyStr.startsWith(CHANNEL_TYPE)) {
				channelKey = Integer.parseInt(keyStr.substring(CHANNEL_TYPE.length()));
				channelMap.put(channelKey, props.getProperty(keyStr));
			} else {
				// 如果不是支付类型，将支付类型名称与支付类型实现类放入到Map中
				IPaymentForCharge encryptor = newInstance(props.getProperty(keyStr));
				if (encryptor != null) {
					paymentManagerMap.put(keyStr, encryptor);
					logger.info("PaymentManager.init put " + key + " to map,class:" + props.getProperty((String) key));
				}
			}
		}
	}

	/**
	 * 通过Clazz字符串生成对象的Class
	 * 
	 * @param paymentClass Clazz字符串
	 * @return 支付对象类
	 * 2016年6月3日 by lh.qiu
	 */
	private static IPaymentForCharge newInstance(String paymentClass) {

		try {

			Class<?> clazz = Class.forName(paymentClass);

			Object obj = clazz.getConstructor().newInstance();

			return (IPaymentForCharge) obj;

		} catch (Exception e) {
			logger.error("PaymentManager.newInstance class have an exception,class:" + paymentClass, e);
			return null;
		}
	}

	/**
	 * 通过properties路径获得对应的properties类
	 * 
	 * @param propertiesPath properties路径
	 * @return properties类
	 * 2016年6月3日 by lh.qiu
	 */
	private static Properties readAsProperties(String propertiesPath) {

		InputStream in = null;
		Properties prop = null;
		try {
			in = Thread.currentThread().getContextClassLoader().getResourceAsStream(propertiesPath);

			prop = new Properties();

			prop.load(in);

		} catch (Exception e) {
			logger.error("PaymentManager.readAsProperties class have an exception,propertiesPath:" + propertiesPath, e);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					logger.error("PaymentManager.readAsProperties close InputStream have an exception", e);
				}
			}
		}

		return prop;
	}
}
